﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using LibrarySync2.Business.FileSystem;
using System.ComponentModel;
using LibrarySync2.Common.Event;
using LibrarySync2.Common.Extensions;
using LibrarySync2.Common.Enum;
using System.Threading;
using FSItem = LibrarySync2.Business.FileSystem.Item;
using LibrarySync2.Common.Interfaces;

namespace LibrarySync2.Business.Worker
{
    public class LibraryCopier
    {
        private DirectoryInfo _tradingPartnerDestinationDirectory;
        public IFileSystemUpdate _updates;

        private BackgroundWorker _copyWorker;

        public bool Running { get; private set; }

        public event EventHandler<CopyEventArgs> CopyEvent;

        public LibraryCopier(DirectoryInfo tradingPartnerDestinationDirectory, IFileSystemUpdate updates)
        {
            if (tradingPartnerDestinationDirectory == null)
                throw new ArgumentNullException("tradingPartnerDestinationDirectory");
            if (updates == null)
                throw new ArgumentNullException("toCopy");
            if (!tradingPartnerDestinationDirectory.Exists)
                throw new ArgumentException(string.Format(
                    "Trading partner destination directory does not exist: '{0}'", tradingPartnerDestinationDirectory.FullName));

            _tradingPartnerDestinationDirectory = tradingPartnerDestinationDirectory;
            _updates = updates;

            _copyWorker = new BackgroundWorker();
            _copyWorker.DoWork += new DoWorkEventHandler(_copyWorker_DoWork);
            _copyWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_copyWorker_RunWorkerCompleted);
            _copyWorker.WorkerSupportsCancellation = true;
        }

        public void Start()
        {
            _copyWorker.RunWorkerAsync();
        }

        public void Cancel()
        {
            _copyWorker.CancelAsync();
        }

        void _copyWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Running = true;
            CopyLibrary();
        }

        void _copyWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            CopyEvent.Raise<CopyEventArgs>(this, new CopyEventArgs(
                e.Cancelled ? CopyStatusType.Cancelled : CopyStatusType.Complete));
   
            Running = false;
        }

        private void CopyLibrary()
        {
            foreach (var updateItem in _updates)
            {
                if (_copyWorker.CancellationPending)
                    return;

                updateItem.MediaFile.CopyToDestination(_copyWorker, CopyEvent,
                    updateItem.MediaFileUpdateType, _tradingPartnerDestinationDirectory,
                    _updates.IncludeMetadata);
            }
        }
    }
}
